﻿#region Copyright and License Notice
// Copyright (C)2010-2016 - Rob Levine and other contributors
// http://configgen.codeplex.com
// 
// This file is part of ConfigGen.
// 
// ConfigGen is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// ConfigGen is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License and 
// the GNU Lesser General Public License along with ConfigGen.  
// If not, see <http://www.gnu.org/licenses/>
#endregion

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using ConfigGen.Core.ConfigurationSettings;
using NUnit.Framework;

namespace ConfigGen.Core.Tests.ConfigurationSettings
{
    [TestFixture]
    public class SearchableXmlTests
    {
        [Test]
        public void ConfigurationSetting_NotNull()
        {
            var configurationSetting = new ConfigurationSetting("token", "value");

            using (var ms = new MemoryStream())
            using (var writer = new XmlTextWriter(ms, Encoding.UTF8))
            using (var reader = new StreamReader(ms))
            {
                var itemUnderTests = new SearchableXmlConverter();
                itemUnderTests.ToSearchableXml(configurationSetting, writer);
                writer.Flush();
                ms.Position = 0;
                string xml = reader.ReadToEnd();

                Assert.AreEqual("<token>value</token>", xml.Trim());
            }
        }

        [Test]
        public void ConfigurationSetting_Null()
        {
            var configurationSetting = new ConfigurationSetting("token", null);

            using (var ms = new MemoryStream())
            using (var writer = new XmlTextWriter(ms, Encoding.UTF8))
            using (var reader = new StreamReader(ms))
            {
                var itemUnderTests = new SearchableXmlConverter();
                itemUnderTests.ToSearchableXml(configurationSetting, writer);
                writer.Flush();
                ms.Position = 0;
                string xml = reader.ReadToEnd();

                Assert.AreEqual(string.Empty, xml.Trim());
            }
        }

        [Test]
        public void MachineConfigurationSettings()
        {
            var settings = new List<ConfigurationSetting>
                               {
                                   new ConfigurationSetting("token1", "value1"),
                                   new ConfigurationSetting("token2", "value2")
                               };

            var configurationSettings = new MachineConfigurationSettings("machineName", "configFilePath", settings);

            //<Machine name="machineName" configFilePath="configFilePath">
            //  <Values>
            //      <token1>value1</token1>
            //      <token2>value2</token2>
            //  </Values>
            //</Machine>

            using (var ms = new MemoryStream())
            using (var writer = new XmlTextWriter(ms, Encoding.UTF8))
            {
                var itemUnderTests = new SearchableXmlConverter();
                itemUnderTests.ToSearchableXml(configurationSettings, writer);
                writer.Flush();
                ms.Position = 0;

                var dom = new XmlDocument();
                dom.Load(ms);
                Console.WriteLine(dom.OuterXml);

                Assert.IsNotNull(dom.DocumentElement, "Root element: missing");
                Assert.AreEqual("Machine", dom.DocumentElement.LocalName, "Root element: incorrect local name");
                var machineNameAttribute = dom.DocumentElement.Attributes.GetNamedItem("name");
                Assert.IsNotNull(machineNameAttribute, "name attribute: missing");
                Assert.AreEqual("machineName", machineNameAttribute.Value, "name attribute: incorrect value");
                var configFilePath = dom.DocumentElement.Attributes.GetNamedItem("configFilePath");
                Assert.IsNotNull(configFilePath, "configFilePath attribute: missing");
                Assert.AreEqual("configFilePath", configFilePath.Value, "configFilePath attribute: incorrect value");

                Assert.IsNotNull(dom.SelectSingleNode("/Machine/Values/token1"), "token1 element: not found");
                Assert.IsNotNull(dom.SelectSingleNode("/Machine/Values/token2"), "token2 element: not found");
            }
        }

        [Test]
        public void MachineConfigurationSettingsCollection()
        {
            var configurationSettings = new List<MachineConfigurationSettings>
                                            {
                                                new MachineConfigurationSettings("machine1", "path1", new List<ConfigurationSetting>()),
                                                new MachineConfigurationSettings("machine2", "path2", new List<ConfigurationSetting>()),
                                            };
            var configurationSettingsCollection = new MachinesConfigurationCollection(configurationSettings);

            //<MachineConfigurationRoot>
            //  <Machines>
            //      <Machine name="machine1" configFilePath="path1">
            //          <Values />
            //      </Machine>
            //      <Machine name="machine2" configFilePath="path2">
            //          <Values />
            //      </Machine>
            //  </Machines>
            //</MachineConfigurationRoot>

            using (var ms = new MemoryStream())
            using (var writer = new XmlTextWriter(ms, Encoding.UTF8))
            {
                var itemUnderTests = new SearchableXmlConverter();
                itemUnderTests.ToSearchableXml(configurationSettingsCollection, writer);
                writer.Flush();
                ms.Position = 0;

                var dom = new XmlDocument();
                dom.Load(ms);
                Console.WriteLine(dom.OuterXml);

                Assert.IsNotNull(dom.DocumentElement, "Root element: missing");
                Assert.AreEqual("MachineConfigurationRoot", dom.DocumentElement.LocalName, "Root element: incorrect local name");
                Assert.IsNotNull(dom.SelectSingleNode("/MachineConfigurationRoot/Machines/Machine[@name='machine1']"), "machine1 machine element: not found");
                Assert.IsNotNull(dom.SelectSingleNode("/MachineConfigurationRoot/Machines/Machine[@name='machine2']"), "machine2 machine element: not found");
            }
        }
    }
}
